﻿ 
namespace Common.Algorithm.Core.LocalTest;

public class QuadTreeExecute
{

    public static string filePath { get; set; }
    public static int dataNum { get; set; }

    public static Point[] Coordinate;

    public static List<GeometryTest> geometryTests { get; set; } = new List<GeometryTest>();

    private static Random random { get; set; } = new Random();
    public QuadTreeExecute()
    {
        GetData();
        List<GeometryTest> geometries = geometryTests = BuildGeoms(); //拿到图形对象


        //geometries.ForEach(g =>
        //    g.positon = new Point2d(random.Next(0, 2000), random.Next(0, 2000)));
        //geometryTests = geometries = geometries.GetRange(0, 8).ToList();

        var minPntX = geometries.Min(g => g.positon.X - 100);
        var maxPntX = geometries.Max(g => g.positon.X + 100);
        var minPntY = geometries.Min(g => g.positon.Y - 100);
        var maxPntY = geometries.Max(g => g.positon.Y + 100);
        Rectangle maxRect = new Rectangle(new Point2d(minPntX, minPntY), new Point2d(maxPntX, maxPntY));//读取到整个图形的最大区域

        Func<GeometryTest, Rectangle> func = (geo) => { return geo.GenRect(); };

        //新建四叉树对象
        QuadTreeNode<GeometryTest> qtr = new QuadTreeNode<GeometryTest>(maxRect, 0);
        QuadTreeNode<GeometryTest>.getBBoxFunc = func;
        //将对象插入四叉树完成构建
        foreach (var geo in geometries)
        {
            qtr.Insert(geo);//插入对象
        }
        Console.WriteLine("-------------");
        var nodes = qtr.GetAllNodes();
        Console.WriteLine(nodes.Count());
        Console.WriteLine(nodes.Where(n => n.items.Count != 0).Count());

        rects = nodes.Select(n => n.envelop).ToList();
    }
    public static List<Rectangle> rects { get; set; }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="Path"></param>
    /// <param name="N"></param>
    public static void GetData()
    {
        int i = 0;
        Coordinate = new Point[dataNum];
        using (StreamReader sr = new StreamReader(filePath, System.Text.Encoding.Default))
        {
            string line;
            while ((line = sr.ReadLine()) != null && i <= dataNum - 1)
            {
                string[] point = line.Split(" ");
                Coordinate[i].X = (int)double.Parse(point[0]);
                Coordinate[i].Y = (int)double.Parse(point[1]);
                i++;
            }
        }
    }

    public static List<GeometryTest> BuildGeoms()
    {
        List<GeometryTest> geometries = new List<GeometryTest>();
        for (int i = 0; i < Coordinate.Length; i++)
        {
            var pnt = Coordinate[i];
            var geom = new GeometryTest();
            geom.id = i;
            geom.positon = new Point2d(pnt.X, pnt.Y);
            geom.raidus = 1;
            geometries.Add(geom);
        }
        return geometries;
    }

    public class GeometryTest
    {
        public int id { get; set; }
        public Point2d positon { get; set; }
        public double raidus { get; set; } = 2d;

        public Rectangle GenRect()
        {
            return new Rectangle(
                    new Point2d(positon.X - raidus, positon.Y - raidus),
                    new Point2d(positon.X + raidus, positon.Y + raidus));
        }
    }
}
